package org.jeecg.modules.door.stocket;

import org.apache.http.util.TextUtils;
import org.apache.tomcat.util.buf.HexUtils;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.door.entity.LwgyDoorInfo;
import org.jeecg.modules.door.service.ILwgyDoorInfoService;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;

public class SocketServer {
    public static final int PORT = 8888;//监听的端口号
    public String[] response = new String[19];
    public String number;
    @Autowired
    private ILwgyDoorInfoService lwgyDoorInfoService;

    public static void main(String[] args) {
        System.out.println("服务器启动...\n");
        SocketServer server = new SocketServer();
        server.init();
    }

    public void init() {
        try {
            ServerSocket serverSocket = new ServerSocket(PORT);
            while (true) {
                // 一旦有堵塞, 则表示服务器与客户端获得了连接
                Socket client = serverSocket.accept();
                System.out.println("已经链接");
                // 处理这次连接
                new HandlerThread(client);
            }
        } catch (Exception e) {
            System.out.println("服务器异常: " + e.getMessage());
        }
    }

    private class HandlerThread implements Runnable {
        private Socket socket;
        public HandlerThread(Socket client) {
            socket = client;
            new Thread(this).start();
        }
        /*
        * 读取锁状态（扩展功能）
        * */

        public void run() {
            try {
                System.out.println("与客户端交互");
                //传指令
                String dataToSend = "04 41 80 21 00 16";

                // 构造要发送的十六进制字符串
                byte[] hexData = util.hexStrToBinaryStr(dataToSend); // 自定义函数HexUtils中有转换方法

                // 向服务器发送数据
                //得到socket 读写流
                OutputStream outputStream = socket.getOutputStream();
                InputStream inputStream = socket.getInputStream();
                outputStream.write(hexData);

                //将对端返回的数据进行解析
                // 读取从服务器返回的数据
                System.out.println("1");
                //StringBuilder response = new StringBuilder();
                //String[] response = new String[19];
                byte[] buf = new byte[1024];
                int length = inputStream.read(buf);
                for (int i = 0; i < length; i++) {
                    //对端返回的是16进制数，但是字节需要先用10进制存，下面意思是读取1个字节并用10进制可读取的int表示
                    int tenSys = buf[i] & 0xFF;
                    // toHexString作用是10进制转16进制数据
                    //需要将16进制数还原处理来，将值转成16进制字符串，一字节等于两位的16进制数
                    String ten =  Integer.toHexString(tenSys);
                    if(ten.length()<2){
                        ten="0"+ten;
                    }
                    System.out.println("循环收到的响应：response:"+i+ten);

                   // response.append(ten);
                    response[i]=ten;
                }
                //解析返回的数据
                //04 41 00 21 0d 11 11 03 17 ff f1 e0 3e 05 00 4b 16
               // A0A1  0021   0d 状态字(常开、暂时开、关锁、反锁（11、12、21、22）)
                // 开锁方式(密码、管理卡、使用卡、机械钥匙、非法开锁、远程开锁（30 、31、32、33、34、35）)
                //  关门状态(正常、不正常（11、22关闭不严）) 电池欠压(电池电压 1位定点小数，例如6.1V ，表示为十六进制值：3d)D14 温度  32℃ 表示成 0x20
                // 最后开锁卡号(卡号、手机号、微机编码)   电池电压  温度 开关锁次数 16
                    String targetDoor = response[0]+response[1];
                    System.out.println(targetDoor);
                        if(targetDoor.equals("0441")){
                            System.out.println("------------------------------");
                            LwgyDoorInfo lwgyDoorInfo = new LwgyDoorInfo();
                            lwgyDoorInfo.setId(UUIDGenerator.generate());
                            lwgyDoorInfo.setLockNumber(targetDoor);
                            lwgyDoorInfo.setLockStatus(response[5]);//锁状态
                            lwgyDoorInfo.setUnlockingMethod(response[6]);//开锁方式
                            lwgyDoorInfo.setClosingStatus(response[7]);//关门状态
                            lwgyDoorInfo.setVoltage(response[13]);//电池电压//D13电池电压 1位定点小数，例如6.1V ，表示为十六进制值：3d；
                            lwgyDoorInfo.setTemperature(response[14]);//温度  32℃ 表示成 0x20。
                           // lwgyDoorInfo.setTimes(response[16]+response[17]);//D15D16 开关锁次数统计：包括开锁、关锁的总次数，用于统计开关锁的频度。1300次 = 0x0546 = D15(05)D16(56).
                            lwgyDoorInfo.setStatus("0");
                            lwgyDoorInfoService.save(lwgyDoorInfo);
                        }

                //4.关闭资源
                outputStream.flush();
                inputStream.close();
                outputStream.close();
                socket.close();
            } catch (Exception e) {

                System.out.println("服务器 run 异常: " + e.getMessage());
                System.out.println("服务器 run 异常: " + e);

            } finally {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (Exception e) {
                        socket = null;
                        System.out.println("服务端 finally 异常:" + e.getMessage());
                    }
                }
            }
        }
    }

    private static String toHexString(byte[] data) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.length; ++i) {
            sb.append(Integer.toString((data[i] & 0xff) + 0x100, 16).substring(1));
        }
        return sb.toString();
    }

    public String[] findInfoByOther(String num){//0441
        System.out.println("==============跳转===================");
        try (ServerSocket serverSocket = new ServerSocket(8888)) {
            System.out.println("Server started. Waiting for client connection...");

            Socket clientSocket = serverSocket.accept();
            System.out.println("Client connected: " + clientSocket);

            InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream();
            // 发送响应数据
            String responseHex = num+" 80 21 00 16";

            byte[] hexData = util.hexStrToBinaryStr(responseHex); // 自定义函数HexUtils中有转换方法
            byte[] hexData2 = util.HexMessageToByteArray(responseHex); // 自定义函数HexUtils中有转换方法
           // outputStream.write(hexData2);
            // 将16进制消息转换为字节数组
            byte[] messageBytes = {(byte) 0x04, 0x41, (byte) 0x80, 0x21, 0x00, 0x16};
            System.out.println("=============16数据："+messageBytes);
            outputStream.write(messageBytes);
            System.out.println("=============发送数据："+hexData);
            System.out.println("=============发送数据："+hexData2);
            System.out.print("转换后的字节数组: [");
            for (byte b : hexData) {
                System.out.print(b + " ");
            }
            System.out.println("]");
            for (byte b : hexData2) {
                System.out.print(b + " ");
            }
            System.out.println("]");


            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) != -1) {
                for (int i = 0; i < len; i++) {
                    //对端返回的是16进制数，但是字节需要先用10进制存，下面意思是读取1个字节并用10进制可读取的int表示
                    int tenSys = buffer[i] & 0xFF;
                    // toHexString作用是10进制转16进制数据
                    //需要将16进制数还原处理来，将值转成16进制字符串，一字节等于两位的16进制数
                    String ten =  Integer.toHexString(tenSys);
                    if(ten.length()<2){
                        ten="0"+ten;
                    }
                    System.out.println("循环收到的响应：response:"+i+ten);

                    // response.append(ten);
                    response[i]=ten;
                }



            /*    String hexString = bytesToHex(buffer, len);
                System.out.println("Received hex data: " + hexString);//收

                // 在这里可以添加解析16进制数据的逻辑
                byte[] bytes = hexStringToBytes(hexString);
                System.out.println("解析得到的字节数组:"+bytes);
                for (byte b : bytes) {
                    System.out.print(b + " ");
                }*/
                //4.关闭资源
                outputStream.flush();
                inputStream.close();
                outputStream.close();
                serverSocket.close();
                return response;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return null;
}


    public Boolean setUpdateInfo(String num){//0441
        System.out.println("==============设置上传指令===================");
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("Server started. Waiting for client connection...");

            Socket clientSocket = serverSocket.accept();
            System.out.println("Client connected: " + clientSocket);

            InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream();
            // 发送响应数据
            String responseHex = num+" 80 21 00 16";

            byte[] hexData = util.hexStrToBinaryStr(responseHex); // 自定义函数HexUtils中有转换方法
            byte[] hexData2 = util.HexMessageToByteArray(responseHex); // 自定义函数HexUtils中有转换方法
            // outputStream.write(hexData2);
            // 将16进制消息转换为字节数组
            byte[] messageBytes = {(byte) 0x04, 0x41, (byte) 0x80, 0x21, 0x00, 0x16};
            System.out.println("=============16数据："+messageBytes);
            outputStream.write(messageBytes);
            System.out.println("=============发送数据："+hexData);
            System.out.println("=============发送数据："+hexData2);
            System.out.print("转换后的字节数组: [");
            for (byte b : hexData) {
                System.out.print(b + " ");
            }
            System.out.println("]");
            for (byte b : hexData2) {
                System.out.print(b + " ");
            }
            System.out.println("]");


            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) != -1) {
                for (int i = 0; i < len; i++) {
                    //对端返回的是16进制数，但是字节需要先用10进制存，下面意思是读取1个字节并用10进制可读取的int表示
                    int tenSys = buffer[i] & 0xFF;
                    // toHexString作用是10进制转16进制数据
                    //需要将16进制数还原处理来，将值转成16进制字符串，一字节等于两位的16进制数
                    String ten =  Integer.toHexString(tenSys);
                    if(ten.length()<2){
                        ten="0"+ten;
                    }
                    System.out.println("循环收到的响应：response:"+i+ten);

                    // response.append(ten);
                    response[i]=ten;
                }



            /*    String hexString = bytesToHex(buffer, len);
                System.out.println("Received hex data: " + hexString);//收

                // 在这里可以添加解析16进制数据的逻辑
                byte[] bytes = hexStringToBytes(hexString);
                System.out.println("解析得到的字节数组:"+bytes);
                for (byte b : bytes) {
                    System.out.print(b + " ");
                }*/
                //4.关闭资源
                outputStream.flush();
                inputStream.close();
                outputStream.close();
                serverSocket.close();
                return true ;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }


    private static String bytesToHex(byte[] bytes, int len) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < len; i++) {
            sb.append(String.format("%02X", bytes[i]));
        }
        return sb.toString();
    }

    private static byte[] hexStringToBytes(String hexString) {
        int len = hexString.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i+1), 16));
        }
        return data;
    }
    public String[] ByteArrayToStringArray(byte[] byteArray) {
            String[] stringArray = new String[byteArray.length];
            for (int i = 0; i < byteArray.length; i++) {
                stringArray[i] = Byte.toString(byteArray[i]);
            }

            System.out.println("转换后的字符串数组:");
            for (String str : stringArray) {
                System.out.print(str + " ");
            }
            return stringArray;
        }

}

